Entrega grupal

Paquetes necesarios

rm(list = ls())
library(tidyverse)
library(dplyr)
library(glue)
library(forcats)
library(lubridate)
library(extrafont)
library(ggplot2)
library(patchwork)
library(plotly)
library(mapSpain)
library(purrr)

Datos

  • election_data: archivo con las elecciones al congreso
  • cod_mun: archivo con los códigos y nombres de cada municipio
  • abbrev: siglas de cada partido
  • surveys: encuestas electorales desde 1982.
election_data <- read_csv(file = "./data/datos_elecciones_brutos.csv")
cod_mun <- read_csv(file = "./data/cod_mun.csv")
surveys <- read_csv(file = "./data/historical_surveys.csv")
abbrev <- read_csv(file = "./data/siglas.csv")

Limpieza de datos

Nos ocupamos primero de las encuestas:

Eliminar los datos de surveys:

  • se refieran a elecciones anteriores a 2008

  • sean a pie de urna

  • tamaño muestral desconocido o inferior a 500.

  • tenga 1 día o menos de trabajo de campo.

surveys <- 
  surveys|> 
  select(-type_survey) |>
  filter(exit_poll == FALSE) |> 
  filter((field_date_to-field_date_from) > 1) |> 
  filter(size>=500 & !is.na(size)) |> 
  filter(date_elec>'2008-1-1')

Seguimos con los datos electorales

election_data <-
  election_data |>
  select(-c(tipo_eleccion,codigo_distrito_electoral,
            numero_mesas, vuelta))

#Combinamos los codigos para formar id_municipio
election_data <- 
  election_data|> 
  mutate(id_municipio = 
           glue("{codigo_ccaa}{codigo_provincia}{codigo_municipio}")) |> 
  relocate(id_municipio, .before=codigo_ccaa)

election_data <- 
  election_data |> 
  select(-c(codigo_ccaa,codigo_provincia,
            codigo_municipio,participacion_1,participacion_2))

#Configuramos la fecha predeterminada como el día 1 y unimos mes con año 
election_data <- 
  election_data|> 
  mutate(fecha = glue("1-{mes}-{anno}")) |> 
  relocate(fecha, .before=anno) |> 
  mutate(fecha=dmy(fecha)) |> 
  select(-c(anno,mes))

-

#Convertimos a tidy data:

election_data <- 
  election_data |> 
  pivot_longer(
    cols = "BERDEAK-LOS VERDES":
      "COALICIÓN POR MELILLA", 
    names_to = "partidos", 
    values_to = "votos", 
    values_drop_na = TRUE )
#partidos y sus colores:

colores = c("PP"="#1A4CA0",
              "UP"="#542C85",
              "PSOE"="#D50000",
              "PNV"="#018B3F",
              "Cs"="#EB6109",
              "ERC"="#FFCD00",
              "CIU"="#1E3A5F",
              "MP"="#0fddc4",
              "VOX"="#1D7A2A",
              "BNG"="#68abde",
              "EH-BILDU"="#4C9A2A",
              "OTROS"="grey",
              "NA"="black")

Utilizamos la variable partidos para agrupar todos ellos en solo 12:

  • “PP” , “UP”, “PSOE” , “PNV” , “Cs” , “ERC” , “CIU”, “MP” , “VOX”, “BNG”, “EH-BILDU” ,“OTROS”

Manera 1

-

resumen <- 
  election_data |> 
  mutate('siglas' = case_when(
  str_detect(partidos, regex("EZKER BA|ENTESA|PODEM|COMPROMÍS|IZQUIERDA UNIDA|ESQUERRA UNI|ESQUERDA UNI|I\\.U\\.|IU ")) ~ "UP",
  str_detect(partidos, "PP|PARTIDO POPULAR|PARTIT POPULAR") ~ "PP",
  str_detect(partidos, "PNV|PARTIDO NACIONALISTA VASCO") ~ "PNV",
  str_detect(partidos, "PSOE|PSC|PARTIDO SOCIALISTA|PARTIT SOCIALISTA|PARTIT DELS SOCIALISTES |PARTIDO DOS SOCIALISTA") ~ "PSOE",
  str_detect(partidos, "MÁS PAÍS|PAÍS|MÉS COMPROM") ~ "MP",
  str_detect(partidos, "VOX") ~ "VOX",
  str_detect(partidos, "AMAIUR|ARALAR|EUSKO|EUSKAL HERRI|BILDU") ~ "EH-BILDU",
  str_detect(partidos, "ERC|ESQUERRA REPUBLICANA DE C|ESQUERRA REPUBLICANA$|ESQUERRA REPUBLICANA/") ~ "ERC",
  str_detect(partidos, "BNG|BLOQUE") ~ "BNG",
  str_detect(partidos, "CIUTADANS|PARTIDO DE LA CIU") ~ "Cs",
  str_detect(partidos, "CONVERGENCIA I| CONVERGENCIA i|CONVERGÈNCIA|UNIÓ D") ~ "CIU", 
  TRUE ~ "OTROS"
)) 

Manera 2

-

#Primero tenemos que filtrar el dataset abbrev ya que hay partidos que aceptan múltiples siglas 
abbrev_sinrepes <- 
  abbrev |> 
  group_by(denominacion) |> 
  slice(1)

# Ahora juntamos el dataset election_data con abbrev_sinrepes para darle a cada partido su correspondiente abreviatura
resumen_2 <- 
    election_data |> 
    left_join(abbrev_sinrepes,
              by = c('partidos' = 'denominacion'))
  
resumen_2 <- 
  resumen_2 |> 
   mutate(siglas = case_when(
     str_detect(siglas, regex("ARALAR|^EA$|AMAIUR|EH Bildu", ignore_case = TRUE)) ~ 'EH-BILDU',
     str_detect(siglas, regex("EB-B|ENTESA|PODEMOS|EZKERRA|UP-UPeC|I\\.U\\.", ignore_case = TRUE)) ~ 'UP',
     str_detect(siglas, regex("^PP$|P\\.P-E\\.U\\.|PP-PAR|PP-FORO|PP-UPM", ignore_case = TRUE)) ~ 'PP',
     str_detect(siglas, regex("PNV", ignore_case = TRUE)) ~ 'PNV',
     str_detect(siglas, regex("PSOE|PSC|PSPC|PSE", ignore_case = TRUE)) ~ 'PSOE',
     str_detect(siglas, regex("PAÍS|MÉS COMPROM", ignore_case = TRUE)) ~ 'MP',
     str_detect(siglas, regex("VOX", ignore_case = TRUE)) ~ 'VOX',
     str_detect(siglas, regex("C's", ignore_case = TRUE)) ~ 'Cs',
     str_detect(siglas, regex("CiU|CDC|unio.cat", ignore_case = TRUE)) ~ 'CIU',
     str_detect(siglas, regex("ERC", ignore_case = TRUE)) ~ 'ERC',
     str_detect(siglas, regex("BNG|NÓS", ignore_case = TRUE)) ~ 'BNG',
    # Partidos que no aparecen en abbrev que tenemos que incluir'
     str_detect(partidos, regex("PARTIT POPULAR|PARTIDO POPULAR|\\(PP\\)", ignore_case = TRUE)) ~ 'PP',
     str_detect(partidos, regex("CIUTADANS|PARTIDO DE LA CIU", ignore_case = TRUE)) ~ 'Cs',
     str_detect(partidos, regex("CONVERGÈNCIA I", ignore_case = TRUE)) ~ 'CIU',
     str_detect(partidos, regex("IZQUIERDA UNIDA|EZKER ANITZA|ESQUERRA UNIDA|^IU$|PODEMOS|AHAL DUGU|ESQUERDA UNIDA-OS VERDES", ignore_case = TRUE)) ~ 'UP',
     str_detect(partidos, regex("PSOE|SOCIALISTA OBRER ESPANYOL|DOS SOCIALISTAS", ignore_case = TRUE)) ~ 'PSOE',
     str_detect(partidos, regex("(EH Bildu)|PARTIDO POLITICO ARALAR|EUSKO", ignore_case = TRUE)) ~ 'EH-BILDU',
     str_detect(partidos, regex("ESQUERRA REPUBLICANA/CATALUNYA SÍ|ESQUERRA REPUBLICANA$", ignore_case = TRUE)) ~ 'ERC',   
     TRUE ~ 'OTROS'))

Comprobamos si los resultados obtenidos de las 2 maneras son similares:

resumen_agg <- 
  resumen |> 
  group_by(siglas,fecha) |> 
  summarise(total_votos_resumen = sum(votos, na.rm = TRUE),.groups = "drop")

resumen_2_agg <- 
  resumen_2 |> 
  group_by(siglas,fecha) |> 
  summarise(total_votos_resumen_2 = sum(votos, na.rm = TRUE),.groups = "drop")

#filtramos por aquellos donde hay diferencias
resumen_total<-
  resumen_agg |> 
  inner_join(resumen_2_agg,by=c("siglas","fecha")) |> 
  mutate(dif=total_votos_resumen-total_votos_resumen_2) |> 
  filter(dif!=0) |> 
  arrange(desc(dif))

view(resumen)

  • Hemos descubierto que las diferencias principales están en CIU y UP en 2015. Resumen le da 630.000 votos a CIU, pero resumen2 solo 65.000, según la web del ministerio del interior obtuvieron 567.000 1

  • En cuanto a los votos en 2015 para UP, si se suman los de Podemos, Coalición “En Comú Podem”, Coalición “Unidad Popular” y Coalición “Compromís - Podemos - És el Moment”, el ministerio de interior dice que obtuvieron 5.700.000 votos, muy cercano al cálculo de resumen, mientras que resumen2 se queda 500.00 votos corto.

  • Y parecido ocurre para el año 2016 para UP: resumen 4.700.000 vs resumen2 4.200.000 vs ministerio 5.000.000.

  • Por tanto creemos que la agrupación resumen es más precisa y es la que usaremos para el resto del trabajo.

Pregunta_0

  • Mostrar un gráfico con los resultados electorales para cada año.

  • Vamos a hacerlo con una función para que acumule en orden de votos los gráficos según la fecha porque hemos encontrado muchos problemas para que reordenara correctamente haciéndolo de manera agregada.

-

# Ordenamos los datos por año y votos descendentes
resumen_agg <- 
  resumen_agg |> 
  arrange(fecha, desc(total_votos_resumen))

# Calcular el porcentaje de votos para cada partido en cada año
resumen_agg_pct <- 
  resumen_agg |> 
  group_by(fecha) |> 
  mutate(
    total_votos_fecha = sum(total_votos_resumen),  # Calcular el total de votos por año
    porcentaje_votos = (total_votos_resumen / total_votos_fecha) * 100  # Calcular el porcentaje
  ) |>
  ungroup()

# Reordenamos los partidos dentro de cada año según el porcentaje de votos
resumen_agg_pct <- 
  resumen_agg_pct |> 
  group_by(fecha) |> 
  arrange(desc(porcentaje_votos)) |>  
  mutate(siglas = factor(siglas, levels = siglas)) |>  
  ungroup()

Pregunta_0

# Función para generar gráficos individuales por fecha
generar_graficos <- 
  function(datos, colores) {
  # Crear una lista vacía para almacenar los gráficos
  lista_graficos <- list()
  
  # Obtener las fechas únicas
  fechas_unicas <- unique(datos$fecha)
  
  # Iterar sobre cada fecha
  for (fecha_actual in fechas_unicas) {
    # Filtrar los datos para la fecha actual
    datos_filtrados <- datos |> 
      filter(fecha == fecha_actual) |> 
      arrange(porcentaje_votos) |> 
      mutate(siglas = factor(siglas, levels = siglas))  # Reordenar factores solo para esta fecha
    # Convertir la fecha al formato año/mes (mes en letras abreviadas)
    fecha_formateada <- format(as.Date(fecha_actual), "%b %Y")
    # Crear el gráfico para la fecha actual
    grafico <- ggplot(datos_filtrados, aes(x = "", y = porcentaje_votos, fill = siglas)) +
      geom_col(position = "stack", width = 2.5) +  # Barra apilada única
      geom_text( # Etiquetas con porcentaje solo si es mayor que 2 para que se vea bien
        aes(label = ifelse(porcentaje_votos >= 2, paste0(round(porcentaje_votos, 0), "%"), "")),
        position = position_stack(vjust = 0.5),  # Centrar el texto dentro de las barras
        color = "white",  # Texto en color blanco
        size = 2.75,
        fontface = "bold"
      ) +
      coord_flip() +
      scale_fill_manual(values = colores, name = "Partido") +  # Usar colores personalizados
      labs(
        x = NULL,
        y = NULL,
        title = fecha_formateada
      ) +
      theme_minimal(base_size = 14) +
      theme(
        axis.text.x = element_blank(),  # Eliminar elementos no deseados
        axis.ticks.x = element_blank(),
        panel.grid.major.x = element_blank(),
        panel.grid.minor.x = element_blank(),
        plot.title = element_text(size = 9, face = "italic"),
        legend.position = "none"  # Deshabilitar las leyendas individuales
      )
    
    # Agregar el gráfico a la lista
    lista_graficos[[as.character(fecha_actual)]] <- grafico
  }
  
  # Crear el orden de partidos para la leyenda global
orden_leyenda <- 
  c("PSOE", "PP", "UP","Cs","VOX", "ERC", "PNV",  "CIU", "BNG", "EH-BILDU", "MP", "OTROS")

leyenda <- 
  ggplot(resumen_agg_pct, 
         aes(x = siglas, y = 1, fill = siglas)) +
  geom_bar(stat = "identity", width = 0) +  # Asignar valores ficticios a `y`
  scale_fill_manual(values = colores, breaks=orden_leyenda,name = "") +
  theme_void() +
  theme(
    legend.position = "bottom",         # Colocar la leyenda en la parte inferior
    legend.text = element_text(size = 8, family = "Rockwell"),  # Ajustar el tamaño del texto en la leyenda
    legend.key.width = unit(0.5, "cm"),    # Ajustar el ancho de las claves de la leyenda
    legend.direction = "horizontal",       # Disponer la leyenda horizontalmente
    legend.box.spacing = unit(0.5, "cm"),  # Espaciado entre los elementos de la leyenda
    legend.justification = "center"        # Centrar la leyenda
  ) +
  guides(fill = guide_legend(nrow = 1))    # Forzar una sola fila para la leyenda
  
  # Combinar los gráficos en una única columna
  grafico_combinado <- 
    wrap_plots(lista_graficos, ncol = 1) +
    plot_annotation(
      title = "Porcentaje de votos por partido en cada elección",
      theme = theme(plot.title = element_text(hjust = 0.5, size = 16,family = "Rockwell")))
    
  
  # Añadir la leyenda al diseño final con patchwork
  final_plot <- 
    grafico_combinado + leyenda
  
  return(final_plot)
}

# Llamar a la función con los datos y colores
grafico_final <- 
  generar_graficos(resumen_agg_pct, colores)

grafico_final

  • Vamos a visualizar ahora los datos de otra manera, con un gráfico interactivo de líneas:
Code
resumen_agg_pct <- resumen_agg_pct |> 
  mutate(
    fecha_formateada = factor(format(as.Date(fecha), "%b %Y"), levels = format(sort(unique(as.Date(fecha))), "%b %Y"))
  )


grafico <- ggplot(resumen_agg_pct, aes(x = fecha_formateada, y = porcentaje_votos, color = siglas, group = siglas)) +
  geom_line(size = 1) +
  geom_point(size = 2) +
  scale_color_manual(values = colores, name = "") +
  labs(
    title = "Resultados en porcentaje de cada partido en cada elección",
    x = NULL,
    y = NULL
  ) +
  theme_minimal() +
  theme(
    axis.text.x = element_text(angle = 45, hjust = 1),
    panel.grid.major = element_blank(),
    panel.grid.minor = element_blank()
  )

ggplotly(grafico)

Pregunta_1

¿Qué partido fue el ganador en los municipios con más de 100.000 habitantes (censo) en cada una de las elecciones?

# quitar los guiones que separan el cod_mun para poder unirlo después en base a id_municipio 

cod_mun <- 
  cod_mun |> 
  mutate(cod_mun = str_replace_all(cod_mun, "-", ""))

ganadores <- 
  resumen |> 
  filter(censo > 100000) |> 
  group_by(fecha, id_municipio) |> 
  arrange(desc(votos)) |> 
  slice(1) |>  
  summarise(partido_ganador = siglas,
            max_votos = votos,
            censo_municipio = censo) |> 
  ungroup() |> 
  left_join(cod_mun, by = c("id_municipio" = "cod_mun"))

Pregunta_1

¿Qué partido fue el ganador en los municipios con más de 100.000 habitantes (censo) en cada una de las elecciones?

Pregunta_2

¿Qué partido fue el segundo cuando el primero fue el PSOE? ¿Y cuando el primero fue el PP?

segundos <- 
  resumen |> 
  group_by(fecha, siglas) |> 
  summarise(total_votos = sum(votos), .groups = "drop") |>  
  group_by(fecha) |> 
  slice_max(total_votos, n = 5) |> 
  arrange(fecha, desc(total_votos)) |>
  ungroup()

# manera 1
primeros_segundos <- 
  segundos |> 
  group_by(fecha) |> 
  mutate(rank = row_number()) |>  # Clasificar partidos por votos en cada año
  filter(rank <= 2) |>  # Filtrar los dos partidos principales de cada año
  summarise(
    primero = siglas[rank == 1], # partido en primer lugar
    votos_1 = total_votos[rank == 1], # Número de votos del primer lugar
    segundo = siglas[rank == 2],  # partido en segundo lugar
    votos_2 = total_votos[rank == 2]  # Número de votos del segundo lugar
  ) |> 
  ungroup()

-

# Filtrar cuando el primero es PSOE
segundo_cuando_psoe <- 
  primeros_segundos |> 
  filter(primero == "PSOE")
# Filtrar cuando el primero es PP
segundo_cuando_pp <- 
  primeros_segundos |> 
  filter(primero == "PP")

# manera 2
# Reordenar los niveles de 'siglas' en base a 'total_votos' (de mayor a menor)

segundos <- 
  segundos |> 
  group_by(fecha) |> 
  mutate(siglas = fct_reorder(siglas, total_votos, .desc = TRUE)) |> 
  ungroup()

-

resultado <- 
  ggplot(segundos, 
       aes(x = siglas, 
           y = total_votos, 
           fill = siglas)) +
  geom_col(alpha = 0.8, 
           width = 0.7) +
  scale_fill_manual(values = colores)  +
  labs(title = "
       Los cinco partidos principales en votos por año",
       subtitle = "Elecciones después de 2008",
       x = "Año y partido",
       y = "Número de votos",
       fill = "Partido") +
  theme_minimal(base_family = "Rockwell") +
  theme(axis.text.x = element_text(angle = 50),
        axis.title.x = element_blank(),
        legend.position = "bottom") +
  facet_wrap(~fecha, nrow = 1, scales = "free_x")+
  theme(plot.title = element_text(size = 20,face = "bold", , hjust = 0.5),
        plot.subtitle = element_text(size = 13,hjust = 0.5),
        legend.key.size = unit(0.9, "cm"))

resultado

Pregunta_3

  • ¿A quién beneficia la baja participación?
# Calcular la participación por municipio
participacion <- 
  resumen |> 
    group_by(id_municipio, siglas) |> 
    summarise(total_votos = sum(votos, 
                                na.rm = TRUE), 
              .groups = "drop") |> 
    left_join(resumen |> 
      group_by(id_municipio) |> 
      summarise(participacion_total = sum(votos, na.rm = TRUE), .groups = "drop"),
    by = "id_municipio") |> 
    mutate(participacion_relativa = total_votos / participacion_total)


# Calcular la correlación entre participación total y votos relativos
correlacion <- 
  participacion |> 
  group_by(siglas) |> 
  summarise(correlacion = cor(participacion_total, participacion_relativa, use = "complete.obs"))
#Complete.obs se ocupa de los valores NA, no se si hace falta pero por si acaso lo dejo puesto
#Deberían salir nº entre -1 y 1, si está por encima de 0 la correlación es positiva lo que significa que saldría beneficiado si la participación es alta, y al revés con los resultados negativos

#Un coeficiente de correlación POSITIVO significa que, a medida que AUMENTA la participación, la proporción de votos de ese partido tiende a AUMENTAR

#Correlación positiva → Beneficio con alta participación.
#Correlación negativa → Beneficio con baja participación.

#Estamos haciendo la correlación entre estas dos cosas
#Participación total: el total de votos emitidos en un municipio
#Proporción de votos de un partido (participacion relativa): los votos de un partido como fracción de los votos totales.

# Visualización de resultados con un gráfico de barras
grafico_corr <-
  ggplot(correlacion, 
       aes(x = reorder(siglas, correlacion), 
           y = correlacion, 
           fill = siglas)) + 
  geom_col() +
  scale_fill_manual(values = colores) + 
  labs(
    title = "Correlación entre participación y votos por partido",
    subtitle = "La correlación negativa indica que menor participación aumenta los votos",
    x = NULL,
    y = "Correlación",
    fill = "Partidos"
  ) +
  theme_minimal(base_family = "Rockwell")+
  theme(plot.title = element_text(size = 18,face = "bold", hjust = 0.5),
        plot.subtitle = element_text(hjust = 0.5))

grafico_corr

#Otra manera comparando la participación de los distintos años 
#Calculamos la participación total por año, a nivel nacional 
participacion_anual <- resumen |> group_by(fecha) |>
  summarise(participacion_total = sum(votos, na.rm = TRUE))
media_votos_años <- 
  mean(participacion_anual$participacion_total)
#Clasificamos los años según si la participación ha sido más alta de lo normal, media o más baja
participacion_anual <- participacion_anual |>
  mutate(categoria_participacion = case_when(
    participacion_total < media_votos_años ~ "Baja_participacion",
    participacion_total >= media_votos_años ~ "Alta_participacion" ))

#Calculamos los votos históricos por partido 
totales_partido <- resumen |> group_by(siglas) |>
  summarise(votos_totales = sum(votos, na.rm = TRUE))  
  
#Participación relativa por partido y año
participacion_partido <- resumen |> group_by(fecha, siglas) |>
  summarise(votos_partido = sum(votos, na.rm = TRUE), .groups = "drop") |>
  left_join(participacion_anual, by = "fecha") |>
  left_join(totales_partido, by = "siglas") |>
  mutate(participacion_relativa = votos_partido / participacion_total)
#en esta tabla tenemos votos_partido que son los votos de ese partido en esa elección
  #participación_total es el total de votos de la elección de ese año, todos los votantes
  #votos_totales son el total de votos que ha conseguido cada partido en todas las elecciones, suma todos los votos que ha tenido a lo largo de los años 
  #participación_relativa es el total de votos del partido ese año entre el total de votos habidos en esas elecciones
#Analizamos el beneficio por tipo de participación
comparacion <- participacion_partido |>
  filter(categoria_participacion %in% c("Baja_participacion", "Alta_participacion")) |>
  group_by(siglas, 
           categoria_participacion) |>
  summarise(promedio_participacion = mean(participacion_relativa, na.rm = TRUE), .groups = "drop") |>
  pivot_wider(names_from = categoria_participacion, 
              values_from = promedio_participacion) |>
  mutate(beneficio_baja = Baja_participacion - Alta_participacion) |> 
  arrange(desc(beneficio_baja))
# Con el beneficio_baja sacamos la diferencia de porcentaje de votos de cada partido que han tenido los años de elecciones con naja participación entre los años de alta participación
# Los partidos donde beneficio_baja es positivo, significa que salen ganando cuando hay baja participación
#Los partidos con beneficio_baja negativo, significa que pierden votos cuando la participación es alta en las elecciones

Pregunta_4

  • ¿Cómo analizar la relación entre censo y voto? ¿Es cierto que determinados partidos ganan en las zonas rurales?
Code
# ANALIZANDO RELACIÓN ENTRE CENSO Y VOTO

# Calculamos el total de votos por municipio y por fecha electoral
relacion_censo_votos <-
  resumen |> 
  group_by(fecha, id_municipio, censo) |> 
  summarise(Total_votos = sum(votos), .groups = "drop")

# Calcular la correlación entre censo y votos totales
correlacion_1 <-
  cor(relacion_censo_votos$censo, relacion_censo_votos$Total_votos)
print(paste("Correlación entre censo y votos totales:",
            round(correlacion_1, 2)))
[1] "Correlación entre censo y votos totales: 1"
Code
# Visualizar la correlación
ggplot(relacion_censo_votos, 
       aes(x = censo, y = Total_votos)) +
  geom_point(alpha = 0.7, color = "#F4A460", size = 1.3) +
  geom_smooth(method = "lm", 
              color = "#5F4B8B",
              linewidth = 1,
              se = FALSE) +
  labs(
    title = "Relación entre censo y votos totales",
    subtitle = paste("Correlación:", round(correlacion_1, 2)),
    x = "Censo (personas censadas)",
    y = "Votos totales"
  ) +
  theme_minimal(base_family = "Rockwell")+
  theme(plot.title = element_text(size = 18,face = "bold", hjust = 0.5),
        plot.subtitle = element_text(hjust = 0.5))

  • ¿Es cierto que determinados partidos ganan en las zonas rurales?
Code
# ANALIZANDO SI CIERTOS PARTIDOS GANAN MÁS EN ZONAS RURALES QUE EN ZONAS URBANAS
 # Creamos una tabla en donde guardamos el tipo de zona según el censo:  Rural o Urbano
 rurales_urbanas <-
  resumen |> 
  mutate("Zona" = ifelse(censo < 10000, 
                         "Rural", 
                         "Urbano"))
# Calculamos los votos de cada partido para cada tipo de zona en cada elección
votos_por_zona <-
  rurales_urbanas |> 
  group_by(fecha, Zona, siglas) |> 
  summarise(Total_votos = sum(votos), 
            .groups = "drop")
# Creamos el gráfico que muestre las diferencias entre partidos, tipos de zona y fechas de elecciones
ggplot(votos_por_zona, 
       aes(x = siglas, y = Total_votos, fill = Zona)) +
  geom_bar(stat = "identity", position = position_dodge(width = 0.5)) +
  facet_wrap(~ fecha, ncol = 2) + # Dividir gráficos por fecha de elección
  scale_fill_manual(values = c("Rural" = "#1EC2F3", "Urbano" = "#7C20E9"))+
  labs(
    title = "
    Comparación de votos por partido entre zonas rurales y urbanas",
    x = "Siglas",
    y = "Total de Votos",
    fill = "Zona") +
  theme_minimal(base_family = "Rockwell") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1),
        plot.title = element_text(size = 18,face = "bold", hjust = 0.5),
        plot.subtitle = element_text(hjust = 0.5)   )
Code
# Como era de esperar, nos salen 6 gráficos (uno por cada fecha electoral) pero el problema es que puede ser bastante complicado de entender a la hora de exponerlo. Es por ello que creo conveniente poner 3 gráficos pero por separados que muestren cómo ha ido evolucionando los votos a lo largo del tiempo, por ejemplo el gráfico del 2008, el del 2016 y el del 2019
# GRÁFICOS 2008, 2016 Y 2019
# 2008
votos_por_zona_2008 <-
  rurales_urbanas |> 
  filter(fecha == "2008-03-01") |> 
  group_by(Zona, siglas) |> 
  summarise(Total_votos = sum(votos), .groups = "drop")
zona_2008 <-
  ggplot(votos_por_zona_2008, aes(x = siglas, y = Total_votos, fill = Zona)) +
  geom_bar(stat = "identity", position = position_dodge(width = 0.5)) +
  scale_fill_manual(values = c("Rural" = "#1EC2F3", "Urbano" = "#7C20E9")) +
  labs(
    title = "
    Comparación de votos por partido entre zonas rurales y urbanas",
    subtitle = "Fecha: Marzo de 2008",
    x = "Siglas",
    y = "Total de Votos",
    fill = "Zona"
  ) + 
  theme_minimal(base_family = "Rockwell") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1),
        plot.title = element_text(size = 18,face = "bold", hjust = 0.5),
        plot.subtitle = element_text(hjust = 0.5))
# 2016
votos_por_zona_2016 <-
  rurales_urbanas |> 
  filter(fecha == "2016-06-01") |> 
  group_by(Zona, siglas) |> 
  summarise(Total_votos = sum(votos), .groups = "drop")
zona_2016 <- 
  ggplot(votos_por_zona_2016, aes(x = siglas, y = Total_votos, fill = Zona)) +
  geom_bar(stat = "identity", position = position_dodge(width = 0.5)) +
  scale_fill_manual(values = c("Rural" = "#1EC2F3", "Urbano" = "#7C20E9")) +
  labs(
    title = "
    Comparación de votos por partido entre zonas rurales y urbanas",
    subtitle = "Fecha: Junio de 2016",
    x = "Siglas",
    y = "Total de Votos",
    fill = "Zona"
  ) +
  theme_minimal(base_family = "Rockwell") +
  theme(axis.text.x = element_text(angle = 45, 
                                   hjust = 1),
        plot.title = element_text(size = 18,face = "bold", hjust = 0.5),
        plot.subtitle = element_text(hjust = 0.5))
# 2019 (la última)
votos_por_zona_2019 <-
  rurales_urbanas |> 
  filter(fecha == "2019-11-01") |> 
  group_by(Zona, siglas) |> 
  summarise(Total_votos = sum(votos), 
            .groups = "drop")
zona_2019 <-
  ggplot(votos_por_zona_2019, aes(x = siglas, 
                                  y = Total_votos, 
                                  fill = Zona)) +
  geom_bar(stat = "identity", position = position_dodge(width = 0.5)) +
  scale_fill_manual(values = c("Rural" = "#1EC2F3", "Urbano" = "#7C20E9")) + 
  labs(
    title = "
    Comparación de votos por partido entre zonas rurales y urbanas",
    subtitle = "Fecha: Noviembre de 2019",
    x = "Siglas",
    y = "Total de Votos",
    fill = "Zona"
  ) +
  theme_minimal(base_family = "Rockwell") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1),
        plot.title = element_text(size = 18,face = "bold", hjust = 0.5),
        plot.subtitle = element_text(hjust = 0.5))

plotly::ggplotly(zona_2008)

plotly::ggplotly(zona_2016)

plotly::ggplotly(zona_2019)

Pregunta_5

¿Cómo calibrar el error de las encuestas ?

Code
#dar el mismo formato de resumen a surveys

surveys_2 <- 
  surveys |> 
  pivot_longer(cols = "UCD":"EV", names_to = "partidos", values_to = "porcentaje", values_drop_na = TRUE )

# agrupar los partidos 

surveys_2 <- 
  surveys_2 |> 
  mutate(partidos = case_when(
    str_detect(partidos, "UP|IU|PODEMOS|COMPROMIS") ~ "UP",
    str_detect(partidos, "PP") ~ "PP",
    str_detect(partidos, "PNV") ~ "PNV",
    str_detect(partidos, "PSOE") ~ "PSOE",
    str_detect(partidos, "MP") ~ "MP",
    str_detect(partidos, "VOX") ~ "VOX",
    str_detect(partidos, "EH-BILDU|AMAIUR") ~ "EH-BILDU",
    str_detect(partidos, "ERC") ~ "ERC",
    str_detect(partidos, "BNG") ~ "BNG",
    str_detect(partidos, "CS") ~ "Cs",
    str_detect(partidos, "CIU|CDC") ~ "CIU", 
    TRUE ~ "OTROS"
  ))

#el valor porcentaje_estimado que aparece en cada pollster para cada eleccion y partido es la media ya que alexandra y yo hemos pensado que para compararlo con los resultados reales lo más conveniente es tener un único dato por casa, partido y elección, ya que es como aparece en los resultados reales 

casas_encuestadoras <- 
  surveys_2 |> 
  select(c(date_elec,id_pollster,pollster,partidos,porcentaje)) |> #seleccionamos solo las columnas necesarias
  mutate(date_elec = format(as.Date(date_elec), "%Y-%m")) |> #quitamos el día para después no tener problemas en la comparación
  group_by(date_elec, id_pollster, partidos) |> 
  mutate(porcentaje_estimado = mean(porcentaje, na.rm = TRUE)) |>
  distinct(date_elec, id_pollster, partidos, .keep_all = TRUE) |> #eliminar filas repetidas
  select(-porcentaje) # ya no nos sirve


# suma de los votos a nivel nacional por eleccion y partido, se convierte este dato en porcentaje para poder compararlo con los datos de surveys
resultados <- 
  resumen |> 
  mutate(fecha = format(as.Date(fecha), "%Y-%m")) |> 
  group_by(fecha, siglas) |>                      
  summarise(Votos_Totales = sum(votos), .groups = "drop") |> 
  group_by(fecha) |> 
  mutate(Porcentaje_real = Votos_Totales / sum(Votos_Totales) * 100) |> 
  select(fecha, siglas, Porcentaje_real)


comparacion <- 
  casas_encuestadoras |> 
  left_join(resultados, by = c("date_elec" = "fecha", "partidos" = "siglas")) |> #unir por fecha y partido 
  mutate(error = Porcentaje_real - porcentaje_estimado) |> 
  select(date_elec, id_pollster, 
         pollster, partidos, 
         Porcentaje_real, porcentaje_estimado, error)


casas_encuestadoras <- 
  casas_encuestadoras |> 
  rename(fecha = date_elec)


grafico_combinado <- 
  ggplot() +
  geom_bar(data = resultados, 
           aes(x = siglas, y = Porcentaje_real, fill = siglas), 
           stat = "identity", position = "dodge",alpha = 0.7) +   # gráfico de barras con el porcentaje real de votos por partido y elección 
  geom_jitter(data = casas_encuestadoras, 
              aes(x = partidos, y = porcentaje_estimado, text = sprintf('Encuestadora:%s\nEstimado: %.2f%%',pollster,porcentaje_estimado)), 
              shape = 21, size = 0.5, stroke = 0.1,
              color = 'grey',  
              position = position_jitter(width = 0.1, height = 0)) +  # grafico de puntos con porceentajes estimados de cada casa por partido y elección
  labs(title = "Porcentaje de votos reales y estimaciones por partido",
    x = NULL,
    y = "Porcentaje",
    fill = "Partidos") +
  scale_fill_manual(values = colores) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1),
    legend.position = "none") +
  facet_wrap(~fecha) +
  theme_minimal(base_family = "Rockwell") +
  theme(plot.title = element_text(size = 18,face = "bold", hjust = 0.5),
        axis.text.x = element_text(angle = 45, hjust = 1),
        panel.grid.minor = element_blank())



ggplotly(grafico_combinado)

Pregunta_6

¿Qué casas encuestadoras acertaron más y cuáles se desviaron más de los resultados?

# Paso 1: Calcular el error absoluto para cada encuesta
datos_combinados <- casas_encuestadoras |> 
  rename(siglas = partidos) |> 
  inner_join(resultados, by = c("fecha", "siglas")) |> 
  mutate(error_absoluto = abs(porcentaje_estimado - Porcentaje_real))
# Paso 2: Calcular el error promedio por casa encuestadora
error_por_casa <- datos_combinados |> 
  group_by(pollster) |> 
  summarise(error_medio = mean(error_absoluto, na.rm = TRUE)) |> 
  arrange(error_medio)
# Paso 3: Identificar la casa encuestadora más precisa y la que más se desvió
casa_mas_precisa <- 
  error_por_casa |> slice_min(error_medio)
casa_mas_desviada <- 
  error_por_casa |> slice_max(error_medio)
# Visualización de resultados
lista <- list(Error_Promedio_Por_Casa = error_por_casa, Casa_Mas_Precisa = casa_mas_precisa,Casa_Mas_Desviada = casa_mas_desviada)

Pregunta_7

  • Sabemos que en 2019 se realizaron 2 elecciones pero ¿hubo diferencias en el total de gente que asistió a votar?. ¿Que partidos ganaron votos en la segunda ronda y cuales salieron perdiendo?
Code
# Filtrar solo las elecciones que ocurrieron en 2019
eleccion_2019 <-resumen |> 
  filter(year(fecha) == 2019)
# Calculamos la participación total por elección, observamos que en la realizada en abril hay cerca de 2 millones más de votantes que en la de finales del mismo año
participacion_2019 <- eleccion_2019 |> 
  group_by(fecha) |> 
  summarise(participacion_total = sum(votos, na.rm = TRUE)) |> 
  arrange(fecha)
Code
# Comparamos los votos de cada partido en las dos elecciones de 2019
votos_2019 <- eleccion_2019 |> 
  group_by(fecha, siglas) |> 
  summarise(votos_totales = sum(votos, na.rm = TRUE), .groups = "drop") |> 
  pivot_wider(names_from = fecha, values_from = votos_totales) |> 
  mutate(diferencia_votos = `2019-11-01` - `2019-04-01`) |> 
  arrange(desc(diferencia_votos))
#Esto nos devuelve una tabla con los votos de cada grupo de siglas, una columna con la primera elección y otra con la segunda. al final tenemos una tercera columna con la diferencia de votos entre elecciones, los positivos son los partidos que ganaron votos y los negativos los que perdieron electores

Code
#Ahora unos gráficos para observar visualmente las diferencias entre sufragios
max_part <- 
  max(participacion_2019$participacion_total, 
      na.rm = TRUE)
ggplot(participacion_2019, 
       aes(x = as.factor(fecha), 
           y = participacion_total, 
           fill = as.factor(fecha))) +
  geom_bar(stat = "identity", 
           show.legend = FALSE, 
           width = 0.6,
           alpha = 0.9) + 
  scale_fill_manual(values = c("#D72638", "#6A4C93")) +
  labs(
    title = "Participación total en las elecciones de 2019",
    subtitle = "Comparación entre fechas de elecciones",
    x = "Fecha de Elección",
    y = "Total de Votantes (en millones)"
  ) +
  theme_minimal(base_family = "Rockwell")+
  scale_y_continuous(breaks = seq(0, max_part, by = 2e6), 
                     labels = scales::label_number(scale = 1e-6, suffix = "M"))+
  theme(plot.title = element_text(size = 18,face = "bold", hjust = 0.5),
        plot.subtitle = element_text(hjust = 0.5))

Code
# Gráfico de diferencias de votos por partido
max_dif <- 
  max(abs(votos_2019$diferencia_votos), 
      na.rm = TRUE)
ggplot(votos_2019, 
       aes(x = reorder(siglas, diferencia_votos), 
           y = diferencia_votos, 
           fill = diferencia_votos > 0)) +
  geom_bar(stat = "identity", 
           show.legend = FALSE) +
  labs(title = "Diferencia de votos por partido entre abril y noviembre de 2019",
       x = "Partido",
       y = "Diferencia de Votos") +
  theme_minimal(base_family = "Rockwell") +
  scale_fill_manual(values = c("#E57373", "#81C784")) +  # Rojo para pérdidas, verde para ganancias
  scale_y_continuous(
    breaks = seq(-max_dif, max_dif, by = 500000),  # Intervalos de 2M
    labels = scales::label_number(scale = 1e-6, suffix = "M")  # Convertir a millones
  ) +
  coord_flip() +# Para que el gráfico sea horizontal
  theme(plot.title = element_text(size = 18,face = "bold", hjust = 0.5))

Code
#Gráfico superpuesto con los votos en columnas de cada partido
votos_2019_long_temp <- 
  votos_2019 |> 
  pivot_longer(cols = -c(siglas, diferencia_votos),  # Mantener siglas y diferencia_votos, convertir las fechas
               names_to = "fecha",
               values_to = "votos_totales")

votos_2019_long <- 
  votos_2019_long_temp |> 
  group_by(siglas) |> 
  summarise(total_votos = sum(votos_totales, 
                              na.rm = TRUE)) |> 
  right_join(votos_2019_long_temp, by = "siglas") |> 
  mutate(siglas = fct_reorder(siglas, 
                              total_votos, 
                              .desc = TRUE))
ggplot(votos_2019_long, 
       aes(x = siglas, 
           y = votos_totales, 
           fill = as.factor(fecha))) +
  geom_col(position = "identity", alpha = 0.8) +  # Superponer barras con transparencia
  labs(title = "Comparación de votos por partido en las elecciones de 2019",
       x = "Partido",
       y = "Total de Votos",
       fill = "Fecha de elección") +
  theme_minimal(base_family = "Rockwell") +
  scale_fill_manual(values = c("#D72638", "#6A4C93")) +  # Azul para abril, naranja para noviembre
  scale_y_continuous(
    labels = scales::label_number(scale = 1e-6, suffix = "M")  # Convertir a millones
  ) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1),
        plot.title = element_text(size = 18,face = "bold", hjust = 0.5))

Pregunta_8

Elaborar mapas de España con ganadores y participacion por provincia y ccaa

totales_election_data <- 
  election_data |> 
  mutate(provincia = substr(id_municipio, 1, 4)) |> 
  group_by(provincia, fecha) |> 
  summarise(
    total_votos = sum(votos, na.rm = TRUE),
    censo = mean(censo, na.rm = TRUE),
    participacion = total_votos / censo,
    .groups = "drop"
  )
ganadores_todos <- 
  resumen |> 
  mutate(provincia = substr(id_municipio, 1, 4)) |> 
  group_by(fecha, provincia) |>
  summarise(
    partido_ganador = siglas[which.max(votos)],
    max_votos = max(votos),
    total_votos = sum(votos), 
    .groups = "drop"      
  )

-

# Combinar datos de totales y ganadores
ganadores_por_anno <- 
  totales_election_data |> 
  inner_join(ganadores_todos, by = c("provincia", "fecha")) |> 
  # Dividir la columna cpro en codauto  y cpro 
  mutate(codauto = substr(provincia, 1, 2),cpro = substr(provincia, 3, 4))

# Obtener el mapa de provincias
data_provincias <- esp_get_prov()
mapa_datos <- data_provincias |> left_join(ganadores_por_anno, by = "cpro")

ggplot(mapa_datos) + 
  geom_sf(aes(fill = partido_ganador, alpha = participacion), color = "white", size = 0.2) + scale_fill_manual(values = colores, name = "Partido Ganador")+ facet_wrap(~fecha)+
  labs(title = "Ganadores y Participación por Provincia en España",
    subtitle = "Alpha representa la participación") +
  guides(alpha = "none")+ 
  theme_minimal(base_family = "Rockwell")+
  theme(plot.title = element_text(size = 18,face = "bold", hjust = 0.5),
        plot.subtitle = element_text(hjust = 0.5))

Pregunta_9

  • Se suele decir que la población de Zaragoza es una muestra representativa de la población española (por tasas medias de renta, nivel de desigualdad, estructura poblacional o franjas de edad). ¿Son los resultados electorales en Zaragoza extrapolables a la población nacional, excluyendo los votos regionalistas o independentistas? ¿Podríamos inferir los resultados nacionales a partir de una única elección local? ¿Se comporta la población local a la hora de votar igual que la nacional?
Code
#guardamos el id_municipio de la ciudad
muni<-"Zaragoza"
cod_mun_ciu<-cod_mun |> 
  filter(municipio==muni) |> 
  mutate(cod_mun = str_remove_all(cod_mun, "-"))


#calculamos el agregado por fecha y partido en porcentaje
resumen_ciu_pct<-resumen |> 
  filter(id_municipio==cod_mun_ciu$cod_mun) |> 
  group_by(siglas,fecha) |>
  summarise(total_votos = sum(votos, na.rm = TRUE),.groups = "drop") |>
  group_by(fecha) |>
  mutate(total_votos_fecha = sum(total_votos),
    porcentaje_votos = (total_votos / total_votos_fecha) * 100) |>
  ungroup() |>
  arrange(fecha,desc(porcentaje_votos))
  

#comparamos con los resultados nacionales
tabla_comp <- resumen_ciu_pct |> 
  inner_join(resumen_agg_pct, by = c("fecha", "siglas")) |> 
  select(fecha, siglas, porcentaje_votos.x, porcentaje_votos.y) |> 
  rename(pct_voto_local = porcentaje_votos.x, 
         pct_voto_nacional = porcentaje_votos.y) 

#al haber algunos partidos a nivel nacional que no se presentan en el municipio por ser propios de otras regiones, los porcentajes nacionales no suman 100. Vamos a repartir el porcentaje nacional faltante entre todos los partidos que sí están representados de manera ponderada para q sumen 100 y poder comparar más correctamente.

Code
tabla_ajustada <- tabla_comp |> group_by(fecha) |> 
  mutate(
    suma_nacional = sum(pct_voto_nacional),
    faltante = 100 - suma_nacional,         # Porcentaje faltante
    proporcion = pct_voto_nacional / suma_nacional,  # Proporción de cada partido
    ajuste = proporcion * faltante,        # Ajuste proporcional
    pct_voto_nacional_ajustado = pct_voto_nacional + ajuste  # Nuevo porcentaje ajustado
  ) |> 
  mutate(dif=pct_voto_local-pct_voto_nacional_ajustado) |> 
  ungroup() |> 
  select(fecha, siglas, pct_voto_local, pct_voto_nacional_ajustado, dif)

# Gráfico de las diferencias
orden_leyenda <- c("PSOE", "PP", "UP","Cs","VOX", "ERC", "PNV",  "CIU", "BNG", "EH-BILDU", "MP", "OTROS")
Code
tabla_ajustada <- tabla_ajustada |>
  mutate(
    siglas = factor(siglas, levels = orden_leyenda),
    fecha_formateada = factor(format(as.Date(fecha), "%b %Y"), levels = format(sort(unique(as.Date(fecha))), "%b %Y"))
  ) |> arrange(fecha_formateada)

titulo<-glue("Diferencia entre Porcentajes de Votos ({muni} - Nacional)")
gg<- ggplot(tabla_ajustada, aes(x = factor(fecha_formateada), y = dif, fill = siglas)) +
  geom_bar(stat = "identity", position = "dodge") +  # Barras lado a lado
  labs(
    title = titulo,
    x = "",
    y = "",
    fill = ""
  ) +
  scale_fill_manual(values = colores) +  # Colores personalizados
  theme_minimal() +
theme(
axis.text.x = element_text(angle = 45, hjust = 1),  # Rotar etiquetas del eje X
strip.text = element_text(size = 10),              # Tamaño de los títulos en los paneles
panel.spacing = unit(1, "lines")                   # Espaciado entre paneles
)

ggplotly(gg)

El gráfico de diferencias nos da una idea general de cómo se comportan las 2 distribuciones. Aparentemente las diferencias pueden ser muy significativas, entre un 4% y un 8% de votos, que pueden significar muchos escaños, por lo que en principio no parece tener sentido hacer esa extrapolación.

Pregunta_10

Determinar el número de escaños que recibirá cada provincia. ¿Cómo es el reparto de escaños en las provincias? ¿Y en la capital?

# DETERMINAMOS CUÁNTOS ESCAÑOS LE CORRESPONDEN A CADA PROVINCIA
# Escribimos todas las provincias de España (52)
provincias <- 
  c(
  "Álava", "Albacete", "Alicante", "Almería", "Asturias", "Ávila",
  "Badajoz", "Barcelona", "Burgos", "Cáceres", "Cádiz", "Cantabria",
  "Castellón", "Ciudad Real", "Córdoba", "La Coruña", "Cuenca",
  "Gerona", "Granada", "Guadalajara", "Guipúzcoa", "Huelva", "Huesca",
  "Islas Baleares", "Jaén", "León", "Lérida", "Lugo", "Madrid", "Málaga",
  "Murcia", "Navarra", "Orense", "Palencia", "Las Palmas", "Pontevedra",
  "La Rioja", "Salamanca", "Segovia", "Sevilla", "Soria", "Tarragona",
  "Santa Cruz de Tenerife", "Teruel", "Toledo", "Valencia", "Valladolid",
  "Vizcaya", "Zamora", "Zaragoza", "Ceuta", "Melilla"
)
# Sacamos el código de provincia de la variable "id_municipio" y a cada código le asignamos el nombre de su provincia. (Los códigos son obtenidos desde el INE)
resumen_provincias <- 
  resumen |> 
  mutate(id_provincia = substr(id_municipio, 3, 4)) |> 
  relocate(id_provincia, .after = id_municipio) |> 
  mutate(provincia = case_when(
    id_provincia == "01" ~ "Álaba",
    id_provincia == "02" ~ "Albacete",
    id_provincia == "03" ~ "Alicante",
    id_provincia == "04" ~ "Almería",
    id_provincia == "05" ~ "Ávila",
    id_provincia == "06" ~ "Badajoz",
    id_provincia == "07" ~ "Belears, Illes",
    id_provincia == "08" ~ "Barcelona",
    id_provincia == "09" ~ "Burgos",
    id_provincia == "10" ~ "Cáceres",
    id_provincia == "11" ~ "Cádiz",
    id_provincia == "12" ~ "Castellón",
    id_provincia == "13" ~ "Ciudad Real",
    id_provincia == "14" ~ "Córdoba",
    id_provincia == "15" ~ "Coruña, A",
    id_provincia == "16" ~ "Cuenca",
    id_provincia == "17" ~ "Girona",
    id_provincia == "18" ~ "Granada",
    id_provincia == "19" ~ "Guadalajara",
    id_provincia == "20" ~ "Gipuzkoa",
    id_provincia == "21" ~ "Huelva",
    id_provincia == "22" ~ "Huesca",
    id_provincia == "23" ~ "Jaén",
    id_provincia == "24" ~ "León",
    id_provincia == "25" ~ "Lleida",
    id_provincia == "26" ~ "Rioja, La",
    id_provincia == "27" ~ "Lugo",
    id_provincia == "28" ~ "Madrid",
    id_provincia == "29" ~ "Málaga",
    id_provincia == "30" ~ "Murcia",
    id_provincia == "31" ~ "Navarra",
    id_provincia == "32" ~ "Ourense",
    id_provincia == "33" ~ "Asturias",
    id_provincia == "34" ~ "Palencia",
    id_provincia == "35" ~ "Palmas, Las",
    id_provincia == "36" ~ "Pontevedra",
    id_provincia == "37" ~ "Salamanca",
    id_provincia == "38" ~ "Santa Cruz De Tenerife",
    id_provincia == "39" ~ "Cantabria",
    id_provincia == "40" ~ "Segovia",
    id_provincia == "41" ~ "Sevilla",
    id_provincia == "42" ~ "Soria",
    id_provincia == "43" ~ "Tarragona",
    id_provincia == "44" ~ "Teruel",
    id_provincia == "45" ~ "Toledo",
    id_provincia == "46" ~ "Valencia/València",
    id_provincia == "47" ~ "Valladolid",
    id_provincia == "48" ~ "Bizkaia",
    id_provincia == "49" ~ "Zamora",
    id_provincia == "50" ~ "Zaragoza",
    id_provincia == "51" ~ "Ceuta",
    id_provincia == "52" ~ "Melilla"
  )) |> 
  relocate(provincia, .after = id_provincia)
# Vamos a calcular cuántos escaños debe tener cada provincia. Esto es un simple cálculo el cual consiste en dividir el número de personas votantes que viven en cada provincia ("censo" por provincia) entre el número de personas votantes en España ("censo" del país). Ese número hay que multiplicarlo por 248 debido a que el número máximo de escaños son 350 y cada provincia de las 52 que hay debe tener mínimo 2 escaños (excepto Ceuta y Melilla que en vez de 2 escaños es 1 escaño). Entonces serían 350 - 50*2 -2*1 = 248
# Redondeamos el número que nos salga para tener los escaños en números naturales
Escaños_provincia <-
  resumen_provincias |> 
  group_by(fecha, provincia) |> 
  summarise(Provincia_pob = sum(unique(censo)), 
            .groups = "drop") |> 
  mutate(Total_pob = sum(Provincia_pob),
         n_escaños = (Provincia_pob/Total_pob)*248,
         n_escaños = round(n_escaños),
         .by = fecha) |> 
  mutate(n_escaños = case_when(
    provincia == "Ceuta" ~ n_escaños + 1,
    provincia == "Melilla" ~ n_escaños + 1,
    TRUE ~ n_escaños + 2
  ))
# Para que un partido tenga la opción de poder obtener un escaño en una provincia, los votos de ese partido en esa provincia deben de ser superiores al 5% de los votos válidos (votos + votos en blanco) de esa provincia.
# En esta tabla se enseña el umbral de votos mínimo para cada fecha en cada provincia
Umbral_minimo <-
  resumen_provincias |> 
  group_by(fecha, provincia) |> 
  summarise(Votos_validos = 
              sum(unique(votos_candidaturas))
            + sum(unique(votos_blancos))) |> 
  mutate(minimo_votos = Votos_validos * 0.05,
         minimo_votos = round(minimo_votos)) |> 
  ungroup()
# En esta tabla se muestran los votos de cada partido en cada provincia para cada fecha
Votos_partido <- 
  resumen_provincias |> 
  group_by(fecha, provincia, siglas) |> 
  summarise(votos = sum(votos),
            .groups = "drop")
# Unimos estas últimas dos tablas y añadimos un filtro, lo que nos da con los partidos con derecho a escaños en cada provincia. (Los partidos con derecho a escaños serán entonces los que superen el mínimo de votos de cada provincia)
Partidos_con_derecho_escaños <-
  Umbral_minimo |> 
  inner_join(Votos_partido)|> 
  group_by(fecha, siglas, provincia) |> 
  filter(votos >= unique(minimo_votos))
# Para finalizar, tenemos que unir la primera tabla (Escaños_provincia) con la última (Partidos_con_derecho_escaños) para tener, en una misma tabla, los datos que nos interesan: Nº de escaños de cada provincia, nombre de la provincia, votos de los partidos de cada provincia, la fecha y las siglas de cada partido
Escaños_provincia_2 <-
  Escaños_provincia |> 
  left_join(Partidos_con_derecho_escaños) |> 
  select(fecha, provincia, n_escaños, siglas, votos)

Pregunta_10